home *** CD-ROM | disk | FTP | other *** search
- #include <stdio.h>
- #include "global.h"
- #include "mbuf.h"
- #include "ax25.h"
- #include "timer.h"
- #include "lapb.h"
- #include "trace.h"
- #include "socket.h"
-
- static char *decode_type __ARGS((int16 type));
-
- /* Dump an AX.25 packet header */
- void
- ax25_dump(bpp,check)
- struct mbuf **bpp;
- int check; /* Not used */
- {
- char tmp[20];
- char control,pid,seg;
- int16 type;
- int unsegmented;
- struct ax25 hdr;
- struct ax25_addr *hp;
-
- printf("AX25: ");
- /* Extract the address header */
- if(ntohax25(&hdr,bpp) < 0){
- /* Something wrong with the header */
- printf(" bad header!\n");
- return;
- }
- pax25(tmp,&hdr.source);
- printf("%s",tmp);
- pax25(tmp,&hdr.dest);
- printf("->%s",tmp);
- if(hdr.ndigis > 0){
- printf(" v");
- for(hp = &hdr.digis[0]; hp < &hdr.digis[hdr.ndigis]; hp++){
- /* Print digi string */
- pax25(tmp,hp);
- printf(" %s%s",tmp,(hp->ssid & REPEATED) ? "*":"");
- }
- }
- if(pullup(bpp,&control,1) != 1)
- return;
-
- putchar(' ');
- type = ftype(control);
- printf("%s",decode_type(type));
- /* Dump poll/final bit */
- if(control & PF){
- switch(hdr.cmdrsp){
- case COMMAND:
- printf("(P)");
- break;
- case RESPONSE:
- printf("(F)");
- break;
- default:
- printf("(P/F)");
- break;
- }
- }
- /* Dump sequence numbers */
- if((type & 0x3) != U) /* I or S frame? */
- printf(" NR=%d",(control>>5)&7);
- if(type == I || type == UI){
- if(type == I)
- printf(" NS=%d",(control>>1)&7);
- /* Decode I field */
- if(pullup(bpp,&pid,1) == 1){ /* Get pid */
- if(uchar(pid) == PID_SEGMENT){
- unsegmented = 0;
- pullup(bpp,&seg,1);
- printf("%s remain %u",seg & SEG_FIRST ?
- " First seg;" : "",seg & SEG_REM);
- if(seg & SEG_FIRST)
- pullup(bpp,&pid,1);
- } else
- unsegmented = 1;
-
- switch(uchar(pid)){
- case PID_SEGMENT:
- printf("\n");
- break; /* Already displayed */
- case PID_ARP:
- printf(" pid=ARP\n");
- arp_dump(bpp);
- break;
- case PID_NETROM:
- printf(" pid=NET/ROM\n");
- netrom_dump(bpp);
- break;
- case PID_IP:
- printf(" pid=IP\n");
- /* Don't verify checksums unless unsegmented */
- ip_dump(bpp,unsegmented);
- break;
- case PID_X25:
- printf(" pid=X.25\n");
- break;
- case PID_TEXNET:
- printf(" pid=TEXNET\n");
- break;
- case PID_NO_L3:
- printf(" pid=Text\n");
- break;
- default:
- printf(" pid=0x%x\n",pid);
- }
- }
- } else if(type == FRMR && pullup(bpp,tmp,3) == 3){
- printf(": %s",decode_type(ftype(tmp[0])));
- printf(" Vr = %d Vs = %d",(tmp[1] >> 5) & MMASK,
- (tmp[1] >> 1) & MMASK);
- if(tmp[2] & W)
- printf(" Invalid control field");
- if(tmp[2] & X)
- printf(" Illegal I-field");
- if(tmp[2] & Y)
- printf(" Too-long I-field");
- if(tmp[2] & Z)
- printf(" Invalid seq number");
- printf("\n");
- } else
- printf("\n");
-
- }
- static char *
- decode_type(type)
- int16 type;
- {
- switch(uchar(type)){
- case I:
- return "I";
- case SABM:
- return "SABM";
- case DISC:
- return "DISC";
- case DM:
- return "DM";
- case UA:
- return "UA";
- case RR:
- return "RR";
- case RNR:
- return "RNR";
- case REJ:
- return "REJ";
- case FRMR:
- return "FRMR";
- case UI:
- return "UI";
- default:
- return "[invalid]";
- }
- }
-
- /* Return 1 if this packet is directed to us, 0 otherwise. Note that
- * this checks only the ultimate destination, not the digipeater field
- */
- int
- ax_forus(iface,bp)
- struct iface *iface;
- struct mbuf *bp;
- {
- struct mbuf *bpp;
- char buf[AXALEN];
- struct ax25_addr dest,ifcall;
-
- /* Duplicate the destination address */
- if(dup_p(&bpp,bp,0,AXALEN) != AXALEN){
- free_p(bpp);
- return 0;
- }
- if(pullup(&bpp,buf,AXALEN) < AXALEN)
- return 0;
- getaxaddr(&dest,buf);
- memcpy(&ifcall,iface->hwaddr,AXALEN);
- if(addreq(&dest,&ifcall))
- return 1;
- else
- return 0;
- }
-
-